﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Xml.Linq;

using SGP;

namespace ParticleEditor
{
    public partial class ParticleEditor : Form
    {
        // The working directory
        //string directory;

        // The images alpha key
        Color colorKey;

        // The image name
        string imageName;

        // The Image used for the particles
        public int ImageID;

        public int rotx;
        public int roty;

        public bool running;

        // Random Number Generator
        public Random rand;

        // The Emitter
        public Emitter e;

        // Time of last update
        DateTime lastTime;

        // Emitter Timer
        DateTime LastEmit;

        // Individual Particle Data
        public class Particle
        {
            public float Lifetime;
            public DateTime CreationTime;
            public DateTime TimeOfDeath;

            public Color StartColor;
            public Color CurrentColor;
            public Color EndColor;

            public float StartScale;
            public float CurrentScale;
            public float EndScale;

            public PointF Position;
            public PointF Direction;
            public float Velocity;

            public float Rotation;
            public float RotationSpeed;

            public bool Destroy;

            public void Update(float elapsedTime)
            {
                // See if the particle should be destroyed
                if (DateTime.Now > TimeOfDeath || Lifetime == 0)
                {
                    Destroy = true;
                    return;
                }

                // Convert Lifetime to MS
                TimeSpan lifetime = TimeSpan.FromSeconds(Lifetime);

                // Find the Percent of lifetime Expired
                float percent = (float)((DateTime.Now - CreationTime).TotalSeconds / lifetime.TotalSeconds);

                // Determine Current Color
                byte a, r, g, b;

                a = ParticleEditor.Lerp(StartColor.A, EndColor.A, percent);
                r = ParticleEditor.Lerp(StartColor.R, EndColor.R, percent);
                g = ParticleEditor.Lerp(StartColor.G, EndColor.G, percent);
                b = ParticleEditor.Lerp(StartColor.B, EndColor.B, percent);

                CurrentColor = Color.FromArgb(a, r, g, b);

                // Determine Current Scale
                CurrentScale = ParticleEditor.Lerp(StartScale, EndScale, percent);

                // Move the Particle
                PointF MoveVec = new PointF(0, Velocity * elapsedTime);

                double x = MoveVec.X;
                double y = MoveVec.Y;

                MoveVec.X = (float)(x * Math.Cos((double)Rotation) - y * Math.Sin((double)Rotation));
                MoveVec.Y = (float)(x * Math.Sin((double)Rotation) + y * Math.Cos((double)Rotation));

                Position.X += MoveVec.X * elapsedTime;
                Position.Y += MoveVec.Y * elapsedTime;

                Position.X = Position.X + Direction.X * elapsedTime;
                Position.Y = Position.Y + Direction.Y * elapsedTime;

                // Update Rotation
                Rotation += (float)((RotationSpeed * 0.0174532925) * elapsedTime);
            }
        }

        // Emitter
        public class Emitter
        {
            public List<Particle> Particles;

            public Point Position;

            public bool Bursting;
        }

        // Create a new particle
        public Particle CreateParticle()
        {
            Particle p = new Particle();

            p.CurrentColor = Color.FromArgb((int)StartingAlphaUpDown.Value, (int)StartingRedUpDown.Value, (int)StartingGreenUpDown.Value, (int)StartingBlueUpDown.Value);
            p.StartColor = p.CurrentColor;
            p.EndColor = Color.FromArgb((int)EndAlphaUpDown.Value, (int)EndRedUpDown.Value, (int)EndGreenUpDown.Value, (int)EndBlueUpDown.Value);
            float dif = (float)(rand.NextDouble() * (double)LifespanRangeUpDown.Value);
            dif *= ((rand.Next(100) > 50) ? 1 : -1);
            p.Lifetime = (float)LifespanUpDown.Value + dif;
            dif = (float)(rand.NextDouble() * (double)ScaleRangeUpDown.Value);
            dif *= ((rand.Next(100) > 50) ? 1 : -1);
            p.StartScale = (float)StartScaleUpDown.Value + dif;
            p.CurrentScale = p.StartScale;
            p.EndScale = (float)EndScaleUpDown.Value + dif;
            dif = (float)(rand.NextDouble() * (double)XRangeUpDown.Value);
            dif *= ((rand.Next(100) > 50) ? 1 : -1);
            p.Position.X = e.Position.X + (int)dif;
            dif = (float)(rand.NextDouble() * (double)YRangeUpDown.Value);
            dif *= ((rand.Next(100) > 50) ? 1 : -1);
            p.Position.Y = e.Position.Y + (int)dif;
            dif = (float)(rand.NextDouble() * (double)VelocityRangeUpDown.Value);
            dif *= ((rand.Next(100) > 50) ? 1 : -1);
            p.Velocity = (float)VelocityUpDown.Value + dif;
            dif = (float)(rand.NextDouble() * (double)RotationRangeUpDown.Value);
            dif *= ((rand.Next(100) > 50) ? 1 : -1);
            p.Rotation = (float)(((float)StartRotationUpDown.Value + dif) * 0.0174532925);
            dif = (float)(rand.NextDouble() * (double)RotationSpeedRangeUpDown.Value);
            dif *= ((rand.Next(100) > 50) ? 1 : -1);
            p.RotationSpeed = (float)RotationSpeedUpDown.Value + dif;

            p.CreationTime = DateTime.Now;
            p.TimeOfDeath = DateTime.Now.AddSeconds(p.Lifetime);

            p.Destroy = false;
            p.Direction.X = (float)XDir.Value;
            p.Direction.Y = (float)YDir.Value;

            return p;
        }

        // Initialization
        public ParticleEditor()
        {
            InitializeComponent();
            SGP.ManagedDirect3D.Instance.InitManagedDirect3D(GraphicsPanel, true);
            SGP.ManagedTextureManager.Instance.InitManagedTextureManager(SGP.ManagedDirect3D.Instance.Device, SGP.ManagedDirect3D.Instance.Sprite);
            rand = new Random();
            e = new Emitter();
            e.Position = new Point(100, 100);
            e.Bursting = false;
            e.Particles = new List<Particle>();
            ImageID = -1;
            lastTime = DateTime.Now;
            running = true;

            SourceBlendBox.SelectedIndex = 2;
            DestBlendBox.SelectedIndex = 0;

            LastEmit = DateTime.Now;

            // Set the working directory
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            dlg.Description = "Select the working directory. When loading an emitter, the image should be located up one folder, then down into a folder named Graphics.";
            if (dlg.ShowDialog() == DialogResult.OK)
                Directory.SetCurrentDirectory(dlg.SelectedPath);

        }

        // Update Function
        public void UpdateParticles()
        {
            float elapsedTime = (float)(DateTime.Now - lastTime).TotalSeconds;
            lastTime = DateTime.Now;

            for (uint i = 0; i < e.Particles.Count; ++i)
            {
                e.Particles.ElementAt((int)i).Update(elapsedTime);
                if (e.Particles.ElementAt((int)i).Destroy)
                {
                    e.Particles.RemoveAt((int)i);
                    --i;
                }
            }

            // Make Particles if it's looping
            if (e.Particles.Count < MaxParticlesUpDown.Value && LoopingCheckBox.Checked)
            {
                if (LastEmit + TimeSpan.FromSeconds((double)EmissionDelayUpDown.Value) < DateTime.Now)
                {
                    for (uint i = 0; i < EmissionRateUpDown.Value; ++i)
                        e.Particles.Add(CreateParticle());
                    LastEmit = DateTime.Now;
                }
            }

        }

        // Render Function
        public void RenderParticles()
        {
            SGP.ManagedDirect3D.Instance.Clear(GraphicsPanel.BackColor);
            SGP.ManagedDirect3D.Instance.DeviceBegin();
            SGP.ManagedDirect3D.Instance.Sprite.Begin(0);
            SGP.ManagedDirect3D.Instance.Sprite.Flush();
            SGP.ManagedDirect3D.Instance.Device.SetRenderState(Microsoft.DirectX.Direct3D.RenderStates.SourceBlend, SourceBlendBox.SelectedIndex);
            SGP.ManagedDirect3D.Instance.Device.SetRenderState(Microsoft.DirectX.Direct3D.RenderStates.DestinationBlend, DestBlendBox.SelectedIndex);
            SGP.ManagedDirect3D.Instance.Device.SetRenderState(Microsoft.DirectX.Direct3D.RenderStates.AlphaBlendEnable, true);
            SGP.ManagedDirect3D.Instance.Device.SetRenderState(Microsoft.DirectX.Direct3D.RenderStates.AlphaTestEnable,true );
            {
                for (uint i = 0; i < e.Particles.Count(); ++i)
                {
                    Particle p = e.Particles.ElementAt((int)i);
                    if (ImageID != -1)
                        SGP.ManagedTextureManager.Instance.Draw(ImageID, (int)p.Position.X, (int)p.Position.Y, p.CurrentScale, p.CurrentScale, Rectangle.Empty, rotx, roty, p.Rotation, p.CurrentColor.ToArgb());
                }
            }
            SGP.ManagedDirect3D.Instance.Sprite.End();
            SGP.ManagedDirect3D.Instance.DeviceEnd();
            SGP.ManagedDirect3D.Instance.Present();
        }

        #region Color Picker Buttons

        // Open the Color Dialog Box to change the starting color of the particle
        private void StartColorButton_Click(object sender, EventArgs e)
        {
            // Show the Color Dialog Box
            ColorDialog dlg = new ColorDialog();

            // See if the user hit OK
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                // Assign the new colors
                StartingAlphaUpDown.Value = dlg.Color.A;
                StartingRedUpDown.Value = dlg.Color.R;
                StartingBlueUpDown.Value = dlg.Color.B;
                StartingGreenUpDown.Value = dlg.Color.G;
            }
        }

        // Open the Color Dialog Box to change the ending color of the particle
        private void EndColorButton_Click(object sender, EventArgs e)
        {
            // Show the Color Dialog Box
            ColorDialog dlg = new ColorDialog();

            // See if the user hit OK
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                // Assign the new colors
                EndAlphaUpDown.Value = dlg.Color.A;
                EndRedUpDown.Value = dlg.Color.R;
                EndBlueUpDown.Value = dlg.Color.B;
                EndGreenUpDown.Value = dlg.Color.G;
            }
        }

        // Background Color
        private void backgroundColorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Show the Color Dialog Box
            ColorDialog dlg = new ColorDialog();

            // See if the user hit OK
            if (dlg.ShowDialog() == DialogResult.OK)
                // Assign the new colors
                GraphicsPanel.BackColor = dlg.Color;
        }

        #endregion

        // File->Exit
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            running = false;
            Close();
        }

        private void ScaleRangeUpDown_ValueChanged(object sender, EventArgs e)
        {

        }

        // File->New
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Get the image
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.InitialDirectory = Directory.GetCurrentDirectory();
            dlg.Title = "Select an Image";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                if (ImageID != -1)
                    SGP.ManagedTextureManager.Instance.ReleaseTexture(ImageID);
                imageName = dlg.SafeFileName;
                MessageBox.Show("Set the image's color key.");
                ColorDialog d = new ColorDialog();
                if (d.ShowDialog() == DialogResult.OK)
                {
                    colorKey = d.Color;
                    ImageID = SGP.ManagedTextureManager.Instance.LoadTexture(dlg.FileName, d.Color.ToArgb());
                    rotx = SGP.ManagedTextureManager.Instance.GetTextureWidth(ImageID) / 2;
                    roty = SGP.ManagedTextureManager.Instance.GetTextureHeight(ImageID) / 2;
                }
            }
        }

        // Lerp Function
        static public byte Lerp(byte start, byte end, float percent)
        {
            byte r;

            r = (byte)(start + (end - start) * (percent));

            return r;
        }

        static public float Lerp(float start, float end, float percent)
        {
            float r;

            r = start + (end - start) * percent;

            return r;
        }

        // Save the file
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (ImageID == -1)
                MessageBox.Show("No image was selected");

            SaveFileDialog dlg = new SaveFileDialog();
            dlg.AddExtension = true;
            dlg.DefaultExt = ".xml";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                XmlWriter w = XmlWriter.Create(dlg.FileName);
                XmlDocument doc = new XmlDocument();
                XmlElement el = (XmlElement)doc.AppendChild(doc.CreateElement("Root"));
                el = (XmlElement)el.AppendChild(doc.CreateElement("Emitter"));

                el.InnerText = imageName;

                // Write all the attributes, like a boss
                el.SetAttribute("Lifespan", LifespanUpDown.Value.ToString());
                el.SetAttribute("AlphaColor", ((uint)(((int)colorKey.A << 24) | ((int)colorKey.R << 16) | ((int)colorKey.G << 8) | ((int)colorKey.B << 0))).ToString());
                el.SetAttribute("StartColor", ((uint)(((int)StartingAlphaUpDown.Value << 24) | ((int)StartingRedUpDown.Value << 16) | ((int)StartingGreenUpDown.Value << 8) | ((int)StartingBlueUpDown.Value << 0))).ToString());
                el.SetAttribute("EndColor", ((uint)(((int)EndAlphaUpDown.Value << 24) | ((int)EndRedUpDown.Value << 16) | ((int)EndGreenUpDown.Value << 8) | ((int)EndBlueUpDown.Value << 0))).ToString());
                el.SetAttribute("StartScale", StartScaleUpDown.Value.ToString());
                el.SetAttribute("EndScale", EndScaleUpDown.Value.ToString());
                el.SetAttribute("XDirection", XDir.Value.ToString());
                el.SetAttribute("YDirection", YDir.Value.ToString());
                el.SetAttribute("Velocity", VelocityUpDown.Value.ToString());
                el.SetAttribute("Rotation", ((decimal)0.0174532925 * StartRotationUpDown.Value).ToString());
                el.SetAttribute("RotationSpeed", ((decimal)0.0174532925 * RotationSpeedUpDown.Value).ToString());
                el.SetAttribute("SourceBlend", SourceBlendBox.SelectedIndex.ToString());
                el.SetAttribute("DestBlend", DestBlendBox.SelectedIndex.ToString());
                el.SetAttribute("Shape", "0");
                el.SetAttribute("Min", MinParticlesUpDown.Value.ToString());
                el.SetAttribute("Max", MaxParticlesUpDown.Value.ToString());
                el.SetAttribute("LifeRange", LifespanRangeUpDown.Value.ToString());
                el.SetAttribute("ScaleRange", ScaleRangeUpDown.Value.ToString());
                el.SetAttribute("XRange", XRangeUpDown.Value.ToString());
                el.SetAttribute("YRange", YRangeUpDown.Value.ToString());
                el.SetAttribute("VelRange", VelocityRangeUpDown.Value.ToString());
                el.SetAttribute("RotRange", ((decimal)0.0174532925 * RotationRangeUpDown.Value).ToString());
                el.SetAttribute("RotSpeedRange", ((decimal)0.0174532925 * RotationSpeedRangeUpDown.Value).ToString());
                el.SetAttribute("EmissionDelay", EmissionDelayUpDown.Value.ToString());
                el.SetAttribute("EmissionRate", EmissionRateUpDown.Value.ToString());

                doc.WriteContentTo(w);
                w.Flush();
            }
        }

        // Load an XML
        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Load an XML
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "All Files|*.*|Xml Files|*.xml";
            dlg.FilterIndex = 2;

            if (DialogResult.OK == dlg.ShowDialog())
            {
                XElement xRoot = XElement.Load(dlg.FileName);

                IEnumerable<XElement> xTiles = xRoot.Elements();

                foreach (XElement xTile in xTiles)
                {
                    double lifespan = 0, startscale = 0, endscale = 0, rot = 0, rotspeed = 0, liferange = 0, scalerange = 0, rotrange = 0, rotspeedrange = 0, delay = 0;
                    int xdir = 0, ydir = 0, vel = 0, src = 0, dest = 0, min = 0, max = 0, xrange = 0, yrange = 0, velrange = 0, rate = 0;
                    Color alpha = Color.White, start = Color.White, end = Color.White;

                    // Lifespan
                    XAttribute xLife = xTile.Attribute("Lifespan");
                    if (xLife != null)
                        lifespan = Convert.ToDouble(xLife.Value);

                    // Start Color
                    XAttribute xstart = xTile.Attribute("StartColor");
                    if (xstart != null)
                    {
                        uint c = Convert.ToUInt32(xstart.Value);
                        byte a = (byte)(c >> 24);
                        byte r = (byte)(c >> 16);
                        byte g = (byte)(c >> 8);
                        byte b = (byte)(c >> 0);
                        start = Color.FromArgb(a, r, g, b);
                    }

                    // Alpha color
                    XAttribute xAlpha = xTile.Attribute("AlphaColor");
                    if (xAlpha != null)
                    {
                        uint c = Convert.ToUInt32(xAlpha.Value);
                        byte a = (byte)(c >> 24);
                        byte r = (byte)(c >> 16);
                        byte g = (byte)(c >> 8);
                        byte b = (byte)(c >> 0);
                        alpha = Color.FromArgb(a, r, g, b);
                    }

                    // End Color
                    XAttribute xend = xTile.Attribute("EndColor");
                    if (xend != null)
                    {
                        uint c = Convert.ToUInt32(xend.Value);
                        byte a = (byte)(c >> 24);
                        byte r = (byte)(c >> 16);
                        byte g = (byte)(c >> 8);
                        byte b = (byte)(c >> 0);
                        end = Color.FromArgb(a, r, g, b);
                    }

                    // Image
                    string image = xTile.Value;

                    int id = -1;
                    id = SGP.ManagedTextureManager.Instance.LoadTexture("..\\graphics\\" + image, alpha.ToArgb());
                    colorKey = alpha;

                    if (id != -1)
                    {
                        //if (ImageID != -1)
                        //    SGP.ManagedTextureManager.Instance.ReleaseTexture(ImageID);
                        ImageID = id;
                        imageName = image;

                        rotx = SGP.ManagedTextureManager.Instance.GetTextureWidth(ImageID) / 2;
                        roty = SGP.ManagedTextureManager.Instance.GetTextureHeight(ImageID) / 2;
                    }

                    // Start Scale
                    XAttribute xStartScale = xTile.Attribute("StartScale");
                    if (xStartScale != null)
                        startscale = Convert.ToDouble(xStartScale.Value);

                    // End Scale
                    XAttribute xendscale = xTile.Attribute("EndScale");
                    if (xendscale != null)
                        endscale = Convert.ToDouble(xendscale.Value);

                    // X Direction
                    XAttribute xX = xTile.Attribute("XDirection");
                    if (xX != null)
                        xdir = Convert.ToInt32(xX.Value);

                    // Y Direction
                    XAttribute xY = xTile.Attribute("YDirection");
                    if (xY != null)
                        ydir = Convert.ToInt32(xY.Value);

                    // Velocity
                    XAttribute xvel = xTile.Attribute("Velocity");
                    if (xvel != null)
                        vel = Convert.ToInt32(xvel.Value);

                    // Rotation
                    XAttribute xrot = xTile.Attribute("Rotation");
                    if (xrot != null)
                        rot = Convert.ToDouble(xrot.Value);

                    // Rotation speed
                    XAttribute xrs = xTile.Attribute("RotationSpeed");
                    if (xrs != null)
                        rotspeed = Convert.ToDouble(xrs.Value);

                    // Source Blend
                    XAttribute xsb = xTile.Attribute("SourceBlend");
                    if (xsb != null)
                        src = Convert.ToInt32(xsb.Value);

                    // Dest Blend
                    XAttribute xdb = xTile.Attribute("DestBlend");
                    if (xdb != null)
                        dest = Convert.ToInt32(xdb.Value);

                    // Min particles
                    XAttribute xmin = xTile.Attribute("Min");
                    if (xmin != null)
                        min = Convert.ToInt32(xmin.Value);

                    // Max Particles
                    XAttribute xmax = xTile.Attribute("Max");
                    if (xmax != null)
                        max = Convert.ToInt32(xmax.Value);

                    // Life Range
                    XAttribute xlr = xTile.Attribute("LifeRange");
                    if (xlr != null)
                        liferange = Convert.ToDouble(xlr.Value);

                    // Scale range
                    XAttribute xsr = xTile.Attribute("SclaeRange");
                    if (xsr != null)
                        scalerange = Convert.ToDouble(xsr.Value);

                    // XRange
                    XAttribute xxr = xTile.Attribute("XRange");
                    if (xxr != null)
                        xrange = Convert.ToInt32(xxr.Value);

                    // YRange
                    XAttribute xyr = xTile.Attribute("YRange");
                    if (xyr != null)
                        yrange = Convert.ToInt32(xyr.Value);

                    // Velocity range
                    XAttribute xvr = xTile.Attribute("VelRange");
                    if (xvr != null)
                        velrange = Convert.ToInt32(xvr.Value);

                    // Rotation Range
                    XAttribute xrr = xTile.Attribute("RotRange");
                    if (xrr != null)
                        rotrange = Convert.ToDouble(xrr.Value);

                    // Rotation Speed range
                    XAttribute xrsr = xTile.Attribute("RotSpeedRange");
                    if (xrsr != null)
                        rotspeedrange = Convert.ToDouble(xrsr.Value);

                    // Emission Delay
                    XAttribute xed = xTile.Attribute("EmissionDelay");
                    if (xed != null)
                        delay = Convert.ToDouble(xed.Value);

                    // Emission Rate
                    XAttribute xer = xTile.Attribute("EmissionRate");
                    if (xer != null)
                        rate = Convert.ToInt32(xer.Value);

                    // Assign the values
                    LifespanUpDown.Value = (decimal)lifespan;
                    StartingAlphaUpDown.Value = start.A;
                    StartingRedUpDown.Value = start.R;
                    StartingGreenUpDown.Value = start.G;
                    StartingBlueUpDown.Value = start.B;
                    EndAlphaUpDown.Value = end.A;
                    EndRedUpDown.Value = end.R;
                    EndGreenUpDown.Value = end.G;
                    EndBlueUpDown.Value = end.B;
                    StartScaleUpDown.Value = (decimal)startscale;
                    EndScaleUpDown.Value = (decimal)endscale;
                    XDir.Value = xdir;
                    YDir.Value = ydir;
                    VelocityUpDown.Value = vel;
                    StartRotationUpDown.Value = (decimal)rot/(decimal)0.0174532925;
                    RotationSpeedUpDown.Value = (decimal)rotspeed/(decimal)0.0174532925;
                    SourceBlendBox.SelectedIndex = src;
                    DestBlendBox.SelectedIndex = dest;
                    MinParticlesUpDown.Value = min;
                    MaxParticlesUpDown.Value = max;
                    LifespanRangeUpDown.Value = (decimal)liferange;
                    ScaleRangeUpDown.Value = (decimal)scalerange;
                    XRangeUpDown.Value = xrange;
                    YRangeUpDown.Value = yrange;
                    VelocityRangeUpDown.Value = velrange;
                    RotationRangeUpDown.Value = (decimal)rotrange/(decimal)0.0174532925;
                    RotationSpeedRangeUpDown.Value = (decimal)rotspeedrange/(decimal)0.0174532925;
                    EmissionDelayUpDown.Value = (decimal)delay;
                    EmissionRateUpDown.Value = rate;
                }
            }
        }

        private void ParticleEditor_Load(object sender, EventArgs e)
        {

        }

        // End the Program
        public void CloseFunction(object sender, EventArgs e)
        {
            running = false;
        }

        private void GraphicsPanel_Paint(object sender, PaintEventArgs e)
        {

        }

        private void GraphicsPanel_MouseDown(object sender, MouseEventArgs e)
        {
        }

        private void GraphicsPanel_MouseMove(object sender, MouseEventArgs e)
        {
            this.e.Position = e.Location;
        }

        private void GraphicsPanel_Paint_1(object sender, PaintEventArgs e)
        {

        }

        private void GraphicsPanel_Click(object sender, EventArgs e)
        {
            // Burst
            uint BurstSize = (uint)rand.Next((int)MinParticlesUpDown.Value, (int)MaxParticlesUpDown.Value);
            for (uint i = 0; i < BurstSize; ++i)
            {
                if (this.e.Particles.Count > MaxParticlesUpDown.Value)
                    break;
                this.e.Particles.Add(CreateParticle());
            }
        }

        // Randomize values
        private void button1_Click(object sender, EventArgs e)
        {
            // Randomize Lifetime
            if (RandLifeSpanCheck.Checked)
            {
                LifespanUpDown.Value = rand.Next((int)LifespanUpDown.Minimum, (int)LifespanUpDown.Maximum);
                // LifespanRangeUpDown.Value = rand.Next((int)LifespanRangeUpDown.Minimum, (int)LifespanRangeUpDown.Maximum);
            }

            // Randomize StartColor
            if (RandStartColorCheck.Checked)
            {
                StartingAlphaUpDown.Value = rand.Next(255);
                StartingBlueUpDown.Value = rand.Next(255);
                StartingRedUpDown.Value = rand.Next(255);
                StartingGreenUpDown.Value = rand.Next(255);
            }

            // Randomize EndColor
            if (RandEndColorCheck.Checked)
            {
                EndAlphaUpDown.Value = rand.Next(255);
                EndBlueUpDown.Value = rand.Next(255);
                EndRedUpDown.Value = rand.Next(255);
                EndGreenUpDown.Value = rand.Next(255);
            }

            // Randomize Start Scale
            if (RandStartScaleCheck.Checked)
            {
                StartScaleUpDown.Value = rand.Next((int)StartScaleUpDown.Maximum);
            }

            // Randomize end scale
            if (RandEndScaleCheck.Checked)
            {
                EndScaleUpDown.Value = rand.Next((int)EndScaleUpDown.Maximum);
            }

            // Randomize Direction
            if (RandDirCheck.Checked)
            {
                XDir.Value = rand.Next((int)XDir.Minimum, (int)XDir.Maximum);
                YDir.Value = rand.Next((int)YDir.Minimum, (int)YDir.Maximum);
            }

            // Randomize Velocity
            if (RandVelCheck.Checked)
            {
                VelocityUpDown.Value = rand.Next((int)VelocityUpDown.Minimum, (int)VelocityUpDown.Maximum);
            }

            // Randomize Starting Rotation
            if (RandStartRotCheck.Checked)
            {
                StartRotationUpDown.Value = rand.Next((int)StartRotationUpDown.Minimum, (int)StartRotationUpDown.Maximum);
            }

            // Randomize rotation speed
            if (RandRotSpeedCheck.Checked)
            {
                RotationSpeedUpDown.Value = rand.Next((int)RotationSpeedUpDown.Minimum, (int)RotationSpeedUpDown.Maximum);
            }

            // Randomize Blend modes
            if (RandBlendModes.Checked)
            {
                SourceBlendBox.SelectedIndex = rand.Next(1, 16);
                DestBlendBox.SelectedIndex = rand.Next(1, 16);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // Check all randomize boxes
            RandBlendModes.Checked = true;
            RandDirCheck.Checked = true;
            RandEndColorCheck.Checked = true;
            RandEndScaleCheck.Checked = true;
            RandLifeSpanCheck.Checked = true;
            RandRotSpeedCheck.Checked = true;
            RandStartColorCheck.Checked = true;
            RandStartRotCheck.Checked = true;
            RandStartScaleCheck.Checked = true;
            RandVelCheck.Checked = true;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            // UnCheck all randomize boxes
            RandBlendModes.Checked = false;
            RandDirCheck.Checked = false;
            RandEndColorCheck.Checked = false;
            RandEndScaleCheck.Checked = false;
            RandLifeSpanCheck.Checked = false;
            RandRotSpeedCheck.Checked = false;
            RandStartColorCheck.Checked = false;
            RandStartRotCheck.Checked = false;
            RandStartScaleCheck.Checked = false;
            RandVelCheck.Checked = false;
        }

    }
}
